在PostgreSQL上搭建pg_paxos

pg_paxos

pg_paxos可用于跨多个PostgreSQL服务器复制表。通过Paxos记录复制表上的每个INSERT / UPDATE / DELETE。当对表执行查询时,pg_paxos首先确保已应用Multi-Paxos日志中的所有先前查询,从而提供。一致性强通过使用的Paxos算法,pg_paxos对于少数节点(读取:服务器)的故障也是健壮的,例如5个中的2个。此实验性的代码网址为: https://github.com/citusdata/pg_paxos/#the-paxos-algorithm

paxos算法

Paxos(K,V)是一个函数,它在某个组(k)的的组中的所有节点上返回相同的值,并且该值是输入之一(v)中。例如,节点可能会调用的Paxos(” leader','primary = node-a')来分配永久组长.paxos(k,v)首先选择提议编号n(通常为0),然后尝试在两个阶段中获得大多数节点接受的值:

  1. 一)要求大多数节点拒绝具有小于Ñ的数字(或等于较低节点ID)的密钥ķ的提议,并返回任何先前接受的值及其提议编号
    B)如果某个值已被一个或多个接受节点,然后v采用具有最高提议编号的值
  2. 要求第1阶段的响应者接受提议N,其值为V,用于密钥ķ

如果在任何阶段,提议者都无法获得多数人的确认,无论是由于失败还是由于基于提案编号的拒绝,那么它将重新启动,其中n =响应中的最高提案编号+ 1,直到提案成功为止该函数返回诉

  • 1A。确保提议者在大多数人中拥有独占访问权限,它基本上是抢占锁定
  • 1B。确保一旦多数接受一个值就永远不会改变一个值,因为如果没有至少一个节点具有现有值,则提议者不能获得新的多数
    1. 如果多数锁没有被抢占,则达成共识,这意味着任何其他提议仍需要为大多数至少一个节点完成1a中,因此将看到图1b中的值

任何后续提议都将在阶段2中使用相同的值,因此的Paxos始终在所有节点上返回相同的值。

paxos源码安装

安装前的准备

主机 IP
master 192.168.32.150
segment1 192.168.32.151
segment2 192.168.32.152

首先要将centOS系统中安装postgreSQL数据库 版本为PostgreSQL-9.6.0,除此之外明确数据库的两个文件夹的位置bindata

cd /var/postgresql/data

vim pg_hba.conf
#host    all        all         0.0.0.0/0       trust

vim postgresql.conf
#listen_address='*'
#port = 5432

此外需要关闭防火墙和selinux

systemctl stop firewalld.serice  #关闭防火墙
systemctl disable firewalld      #禁止防火墙自动启动
setenforce 0                     #关闭selinux防火墙

正式开始安装

安装前期准备(master+segment 1+segment 2)

首先从git上将代码克隆到本地

git clone https://github.com/citusdata/pg_paxos.git
cd pg_paxos
PATH=/usr/local/postgresql/bin/:$PATH make
sudo PATH=/usr/local/postgresql/bin/:$PATH make install

安装dblink扩展

#进入postgresql 源代码的目录中,注意是源代码!
cd /home/yiyi/postgresql/contrib/dblink
make && make install

安装dblink后创建扩展

su - postgres       #进入postgres用户下
psql
CREATE EXTENSION dblink;
CREATE EXTENSION pg_paxos;

修改配置文件 postgresql.conf

shared_preload_libraries = 'pg_paxos'
pg_paxos.node_id = '独一无二不会混淆的id,自己命名'

修改后需要重启postgresql

#首先进入bin目录下
cd /usr/local/postgresql/bin
#重启postgres
./pg_ctl restart -D /var/postgresql/data/

设置表复制

要使用复制表设置,首先要在所有节点上创建表

CREATE TABLE coordinates (
    x int,
    y int
);
% 在master + segment1 + segment2上创建

接下来在其中一个节点上,调用paxos_create_group创建一个名为paxos的组,节点本身为唯一成员(使用其外部地址定义为连接字符串 )

# 仅在master 节点运行
SELECT paxos_create_group('foxi', 'host=192.168.32.150');
SELECT paxos_replicate_table('foxi', 'coordinates');

要添加另一个节点 (192.168.32.151 ),连接到节点并使用组的名称。

# 在 segement 1 上运行
SELECT paxos_join_group('foxi', 'host=192.168.32.150', 'host=192.168.32.151');
# 在 segement 2 上运行
SELECT paxos_join_group('foxi', 'host=192.168.32.150', 'host=192.168.32.152');

paxos安装后

如何设置元数据

[root@mlocalhost pg_paxos]$ psql
psql (9.6.0)
Type "help" for help.

postgres=# INSERT INTO coordinates VALUES (1,1);
INSERT 0 1
postgres=# INSERT INTO coordinates VALUES (2,2);
INSERT 0 1
postgres=# SELECT * FROM coordinates ;
 x | y
---+---
 1 | 1
 2 | 2
(2 rows)

postgres=# \q



[root@mlocalhost pg_paxos]$ psql 
psql (9.6.0)
Type "help" for help.

postgres=# SELECT * FROM coordinates ;
DEBUG:  Executing: INSERT INTO coordinates VALUES (1,1);
CONTEXT:  SQL statement "SELECT paxos_apply_log($1,$2,$3)"
DEBUG:  Executing: INSERT INTO coordinates VALUES (2,2);
CONTEXT:  SQL statement "SELECT paxos_apply_log($1,$2,$3)"
 x | y
---+---
 1 | 1
 2 | 2
(2 rows)

postgres=# UPDATE coordinates SET x = x * 10;
UPDATE 2
postgres=# \q




[root@mlocalhost pg_paxos]$ psql 
psql (9.6.0)
Type "help" for help.

postgres=# SELECT * FROM coordinates ;
DEBUG:  Executing: INSERT INTO coordinates VALUES (1,1);
CONTEXT:  SQL statement "SELECT paxos_apply_log($1,$2,$3)"
DEBUG:  Executing: INSERT INTO coordinates VALUES (2,2);
CONTEXT:  SQL statement "SELECT paxos_apply_log($1,$2,$3)"
DEBUG:  Executing: UPDATE coordinates SET x = x * 10;
CONTEXT:  SQL statement "SELECT paxos_apply_log($1,$2,$3)"

 x  | y
----+---
 10 | 1
 20 | 2
(2 rows)

更改一致性模型

默认情况下,pg_paxos在每次读取之前向其他节点询问日志中接受的最高轮数。然后,它在日志中应用SQL查询,包括最高可接受的轮数,这确保了强一致性。在某些情况下,低读取延迟可能优于强一致性。pg_paxos.consistency_model设置可以更改为'optimistic',在这种情况下,节点假定它已经了解了先前的写入。乐观一致性模型在没有失败的情况下提供读写一致性,但在发生故障时可能会返回较旧的结果。

SET pg_paxos.consistency_model TO 'optimistic';
SET pg_paxos.consistency_model TO 'strong';

内部表复制功能

执行查询时,在使用表复制时会自动调用以下函数。我们将展示如何明确地调用它们来阐明pg_paxos的内部结构。

paxos_apply_and_append函数(写入时调用)在确保已执行日志中之前的所有查询之后,将SQL查询附加到日志。

SELECT * FROM paxos_apply_and_append(
                current_proposer_id := 'node-a/1251',
                current_group_id := 'ha_postgres',
                proposed_value := 'INSERT INTO coordinates VALUES (3,3)');

paxos_apply_log函数(在SELECT上调用)执行日志中针对给定组的所有SQL查询,这些查询尚未执行,包括整数max_round_num。

SELECT * FROM paxos_apply_log(
                current_proposer_id := 'node-a/1252',
                current_group_id := 'ha_postgres',
                max_round_num := 3);

paxos_max_group_round函数查询大多数主机的最高接受轮数.paxos_max_group_round返回的回合数将大于或等于对paxos_max_group_round调用开始时达成共识(多数已接受)的任何回合。因此,如果节点将日志应用于该轮数,则保证节点看到任何先前的写入 。

SELECT * FROM paxos_max_group_round(
                current_group_id := 'ha_postgres');

直接使用paxos功能

您还可以通过直接调用paxos函数使用pg_paxos实现任意分布式日志。以下查询将值'primary = node -a'附加到组ha_postgres的多Paxos日志中:

SELECT * FROM paxos_append(
                current_proposer_id := 'node-a/1253',
                current_group_id := 'ha_postgres',
                proposed_value := 'primary = node-a');

current_proposer_id是一个值,对于给定的组和舍入,在整个群集中应该是唯一的。这主要用于确定当两个提议者提出相同的值时接受哪个提案。

可以使用以下方法检索多的Paxos日志中的最新值:

SELECT * FROM paxos(
                current_proposer_id := 'node-a/1254',
                current_group_id := 'ha_postgres',
                current_round_num := paxos_max_group_round('ha_postgres'));
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容

  • About:PostgreSQL About 《PostgreSQL 源码分析系列》 PostgreSQL 源码分...
    ty4z2008阅读 8,054评论 1 40
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,790评论 2 89
  • 寻找一种易于理解的一致性算法(扩展版) 摘要 Raft 是一种为了管理复制日志的一致性算法。它提供了和 Paxos...
    yflau阅读 876评论 0 1
  • 儿子上初中一年级,第一次月考不理想,心里自是焦虑。这几天更是对儿子的监督说教升级,升级到娘俩一言不合就吵,儿子被我...
    许议文阅读 166评论 0 1
  • 失败源于坚持,成功也是
    胡加加阅读 93评论 0 0